package com.zzsxy.stonepuzzle;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

/**
 * 由于JFrame是Java源代码 不可更改（不能添加方法），用其他类构建新方法同时可以用JFrame的方法
 */
public class MainFrame extends JFrame implements KeyListener {
    int[][] data = {
            {1,2,3,4},
            {5,6,7,8},
            {9,10,11,12},
            {13,14,15,0}
    };
    int[][] win = {
            {1,2,3,4},
            {5,6,7,8},
            {9,10,11,12},
            {13,14,15,0}
    };

    int row;
    int column;
    int count;



    /**
     * 在构造MainFrame对象时，构造方法直接调用里面的方法
     */
    public MainFrame(){
        //初始化窗体
        initFrame();
        //初始化数据（打乱数据）
        initData();
        //在窗体中显示图片
        painView();
        //移动业务
        this.addKeyListener(this);  //this ： 可调用父类对象（JFrame）的方法 也可调用实现对象的方法


        //设置窗体可见(由于设置窗体可见特殊性)
        setVisible(true);
    }

    /**
 * 初始化数据（打乱二维数组的内容）
 */
    public void initData(){
        Random r = new Random();
        //遍历二维数组
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
                int randomX = r.nextInt(4);
                int randomY = r.nextInt(4);
                int temp = data[i][j];
                data[i][j] = data[randomX][randomY];
                data[randomX][randomY] = temp;
            }
        }

        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
                if (data[i][j] == 0 ){
                    row = i;
                    column = j;
                }
            }
        }
//        System.out.println(row+"---"+column);
        
    }

    /**
     * 初始化窗体
     */
    public void initFrame(){

        //设置窗体大小
        setSize(514,596);
        //设置窗体关闭模式
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        //设置窗体标题
        setTitle("石头迷阵单机版v1.0");
        //设置窗体置顶
        setAlwaysOnTop(true);
        //设置窗体居中
        setLocationRelativeTo(null);
        //取消窗体默认布局
        setLayout(null);
    }

    /**
     * 在窗体中添加图片
     */
    public void painView(){
       //把当前窗体的组件全部移除
        getContentPane().removeAll();
        if (victory()){
            JLabel winnable = new JLabel(new ImageIcon("F:\\Snipaste\\picture\\win.png"));
            winnable.setBounds(124,230,278,88);
            getContentPane().add(winnable);
        }

        JButton but = new JButton("重新开始");
        but.setBounds(350,5,100,20);
        getContentPane().add(but);
        but.setFocusable(false);
        but.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                count = 0;
                initData();
                painView();
            }
        });

        JLabel scrollable = new JLabel("步数:"+count);
        scrollable.setBounds(25,5,100,20);
        getContentPane().add(scrollable);

        //展示图片
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                JLabel image = new JLabel(new ImageIcon("F:\\Snipaste\\picture\\"+ data[i][j] +".png"));
                image.setBounds(50 + 100 * j,90 + 100 * i,100,100);
                /**
                 *frame.getContentPane().add(image);  由于frame的使用超出变量作用范围，所以不能使用 ; 这里可以用super调用父类的方法 或者 直接使用方法（因为没有重写父类的方法）
                  */
                getContentPane().add(image);
            }
        }
        JLabel bgc = new JLabel(new ImageIcon("F:\\Snipaste\\picture\\bgc.png"));
        bgc.setBounds(26,30,450,484);
        super.getContentPane().add(bgc);

        //把移动后的界面 刷新出来
        getContentPane().repaint();
    }

    /**
     * 移动业务
     */
    private  void move(int move) {
        if (victory()){
            return;
        }
        if (move == 37 ){
            if (column==3){
                return;
            }
            //左移动
            //使空白块与右边的方块互换位置
            int temp;
            temp = data[row][column];
            data[row][column] = data[row][column+1];
            data[row][column+1] = temp;
            column++;
            count++;
            //调用painView,显示移动后的界面
            painView();
        } else if (move == 38) {
            if (row==3){
                return;
            }
            //上移动
            //使空白块与下方的方块互换位置
            int temp;
            temp = data[row][column];
            data[row][column] = data[row+1][column];
            data[row+1][column] = temp;
            count++;
            row++;
            //调用painView,显示移动后的界面
            painView();
        }else if (move == 39) {
            if (column==0){
                return;
            }
            //右移动
            //使空白块与左边的方块互换位置
            int temp;
            temp = data[row][column];
            data[row][column] = data[row][column-1];
            data[row][column-1] = temp;
            count++;
            column--;
            //调用painView,显示移动后的界面
            painView();
        }else if (move == 40) {
            if (row==0){
                return;
            }
            //下移动
            //使空白块与上方的方块互换位置
            int temp;
            temp = data[row][column];
            data[row][column] = data[row-1][column];
            data[row-1][column] = temp;
            count++;
            row--;
            //调用painView,显示移动后的界面
            painView();
        } else if (move == 90) {
            //触发作弊器
            data = new int[][]{
                    {1,2,3,4},
                    {5,6,7,8},
                    {9,10,11,12},
                    {13,14,15,0}
            };
            painView();
        }
    }

    /**
     * 判断是否胜利
     */
    public Boolean victory(){
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
                if (data[i][j] != win[i][j]){
                    return false;
                }
            }
        }
        return true;

    }

    @Override
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        move(key);
    }


    @Override
    public void keyReleased(KeyEvent e) {

    }
    //检测不到上下左右按键
    @Override
    public void keyTyped(KeyEvent e) {

    }
}
